<?php

/**
 * Extends PHPTemplate to allow caching of the final output of the template. This allows
 * pages which do not change very often to be served up from their text-based caches and
 * decreases system resource and database usage, especially on high-traffic sites.
 * 
 * PHP versions 4 and 5
 * 
 * Licensed under The MIT License
 * 
 * @author Jacob Wright
 * @copyright		Copyright (c) 2006, Within Code LLC
 * @package			blueprint
 * @version			$Revision: $
 * @modifiedby		$LastChangedBy: $
 * @lastmodified	$Date: 2006-05-25 16:12:33 -0600 (Thu, 25 May 2006) $
 * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
 */

//include_once(dirname(__FILE__) . "/PHPTemplate.php");

class CachedTemplate extends PHPTemplate {
	
	var $cachefile;
	var $expire;
	var $isCached;
	
	/**
	 * Constructor, initializes the template for use
	 * 
	 * @param string $file The path of the template to be used
	 * @param string $uniqueName A unique name specific to the cached page used to set this cache apart from others
	 * @param int $expire The number of minutes that this cache is good for
	 */
	function CachedTemplate($file, $cache, $expire = 15) {
		// Get the filename and the cache directory
		parent::PHPTemplate($file);
		
		mkdir_r(dirname($cache));
		$this->cachefile = $cache;
		$this->expire = $expire*60;
	}
	
	/**
	 * Determines whether the template's cache exists and is not outdated
	 * 
	 * @return boolean Whether or not the template's cache is valid
	 */
	function isCached() {
		if($this->isCached) {
			return true;
		} if(!self::validCache($this->cachefile, $this->expire)) {
			return false;
		} else {
			$this->isCached = true;
			return true;
		}
	}
	
	/**
	 * Determines whether the template's cache exists and is not outdated
	 * 
	 * @return boolean Whether or not the template's cache is valid
	 */
	public static function validCache($file, $expire = 0) {
		$expire *= 60;
		if(!file_exists($file)) {
			return false;
		} elseif($expire && (!($mtime = filemtime($file)) || ($mtime + $expire) < time())) {
			@unlink($file);
			return false;
		} else {
			return true;
		}
	}
	
	/**
	 * Processes the template, writes the cache to file, and returns it's output
	 * 
	 * @return string The final output of the template
	 */
	function fetch() {
		if($this->isCached()) {
			return file_get_contents($this->cachefile);
		} else {
			$contents = parent::fetch();
			$fp = fopen($this->cachefile, 'w');
			fputs($fp, $contents);
			fclose($fp);
			return $contents;
		}
	}
	
	/**
	 * Processes the template, writes the cache to file, and prints it's output to the screen
	 */
	function display() {
		if($this->isCached()) {
			include($this->cachefile);
		} else {
			$contents = parent::fetch();
			$fp = fopen($this->cachefile, 'w');
			fputs($fp, $contents);
			fclose($fp);
			echo $contents;
		}
	}
}

?>